package cn.pli.bike.model;

import com.framemodule.utils.CommonUtils;
import com.framemodule.utils.Logger;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

import cn.pli.bike.App;
import cn.pli.bike.model.http.ChunkingConverterFactory;
import cn.pli.bike.model.http.ResponseCacheConvertFactory;
import cn.pli.bike.model.http.ResponseConvertFactory;
import cn.pli.bike.model.subscribers.ProgramSubscriber;
import cn.pli.bike.url.API;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by kangjie on 2017/9/14.
 */

public class RxService {
    private static final int TIMEOUT_READ = 20;                 //
    private static final int TIMEOUT_CONNECTION = 10;

    //private static CacheInterceptor cacheInterceptor = new CacheInterceptor();
    static Request request;

    /**
     * 创建httpclient
     */
    private static OkHttpClient okHttpClient = new OkHttpClient.Builder()
            //  SSL证书
            //  .sslSocketFactory(TrustManager.getUnsafeOkHttpClient())
            //  .hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
            //  打印日志
            //  .addInterceptor(interceptor)
            //设置Cache
            //      .addNetworkInterceptor(cacheInterceptor)//缓存方面需要加入这个拦截器
            //      .addInterceptor(cacheInterceptor)
            //      .cache(HttpCache.getCache())
            //time out
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    String token = App.getShareSetting().loadString("token");
                    if (CommonUtils.isEmpty(token)) {
                        request = chain.request()
                                .newBuilder()
                                .build();
                    } else {

                        request = chain.request()
                                .newBuilder()
                                .addHeader("token", App.getShareSetting().loadString("token"))
                                .build();
                    }


                    handle(chain);
                    return chain.proceed(request);
                }
            })
            .connectTimeout(TIMEOUT_CONNECTION, TimeUnit.SECONDS)
            .readTimeout(TIMEOUT_READ, TimeUnit.SECONDS)
            .writeTimeout(TIMEOUT_READ, TimeUnit.SECONDS)
            //失败重连
            .retryOnConnectionFailure(true)
            .build();


    //创建网络请求service

    public static <T> T createApi(Class<T> clazz) {
        return createApi(clazz, API.URL.BASE_URL);
    }

    public static <T> T createApi(String cacheKey, ProgramSubscriber programSubscriber, Class<T> clazz) {
        if (!CommonUtils.isEmpty(cacheKey)) {
          /*  if (!CommonUtils.isEmpty(BaseApp.diskLruCacheHelper.getAsString(cacheKey))){

                Type[] genericType = programSubscriber.getClass().getGenericInterfaces();
                programSubscriber.onNext( new Gson().fromJson(BaseApp.diskLruCacheHelper.getAsString(cacheKey),genericType[0]));
            }else {
                programSubscriber.onNext(null);
            }*/

            return createApi(cacheKey, clazz, API.URL.BASE_URL);
        } else {
            return createApi(clazz, API.URL.BASE_URL);
        }

    }


    public static <T> T createApi(Class<T> clazz, ChunkingConverterFactory chunkingConverterFactory) {
        if (chunkingConverterFactory == null) {
            return createApi(clazz, API.URL.BASE_URL);
        } else {
            return createApi(clazz, API.URL.BASE_URL, chunkingConverterFactory);
        }

    }

    public static <T> T createApi(Class<T> clazz, String url, ChunkingConverterFactory chunkingConverterFactory) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .client(okHttpClient)
                //       .addConverterFactory(chunkingConverterFactory)
                //     .addConverterFactory(new TypedFileMultiPartBodyConverterFactory())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())               //转化为被观察者模式
                .addConverterFactory(GsonConverterFactory.create())                     //
                .build();
        return retrofit.create(clazz);

    }


    public static <T> T createApi(Class<T> clazz, String url) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .client(okHttpClient)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(ResponseConvertFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        return retrofit.create(clazz);
    }

    /**
     * 需要缓存
     *
     * @param clazz
     * @param url
     * @param <T>
     * @return
     */
    public static <T> T createApi(String cacheKey, Class<T> clazz, String url) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .client(okHttpClient)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                //   .addConverterFactory(ResponseConvertFactory.create())
                .addConverterFactory(ResponseCacheConvertFactory.create(cacheKey))
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        return retrofit.create(clazz);
    }


    static class FileRequestBodyConverterFactory extends Converter.Factory {
        @Override
        public Converter<File, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
            return new FileRequestBodyConverter();
        }
    }

    static class FileRequestBodyConverter implements Converter<File, RequestBody> {

        @Override
        public RequestBody convert(File file) throws IOException {
            return RequestBody.create(MediaType.parse("multipart/form-data"), file);
        }
    }

    private static void handle(Interceptor.Chain chain) {
        Request request = chain.request();
        RequestBody requestBody = request.body();

        String body = "";
        if (requestBody == null) {
            return;
        }
        if (!requestBody.contentType().toString().contains("multipart")) {
            if (requestBody != null) {
                Buffer buffer = new Buffer();

                try {
                    requestBody.writeTo(buffer);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Charset charset = Charset.forName("UTF-8");
                MediaType contentType = requestBody.contentType();

                if (contentType != null && !contentType.subtype().contains("multipart")) {
                    charset = contentType.charset(charset);
                    body = buffer.readString(charset);
                }
            }

        }
        Logger.d("url" + request.method() + request.url() + request.headers() + body);


    }
}
